home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Tool Chest / Development Kits / • Other Platforms / PCCTS 1.31 / h / AParser.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-10  |  8.1 KB  |  260 lines  |  [TEXT/MPS ]

  1. /* ANTLRParser.h
  2.  *
  3.  * Define the generic ANTLRParser superclass, which is subclassed to
  4.  * define an actual parser.
  5.  *
  6.  * Before entry into this file: TokenType must be set.
  7.  *
  8.  * SOFTWARE RIGHTS
  9.  *
  10.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  11.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  12.  * company may do whatever they wish with source code distributed with
  13.  * PCCTS or the code generated by PCCTS, including the incorporation of
  14.  * PCCTS, or its output, into commerical software.
  15.  * 
  16.  * We encourage users to develop software with PCCTS.  However, we do ask
  17.  * that credit is given to us for developing PCCTS.  By "credit",
  18.  * we mean that if you incorporate our source code into one of your
  19.  * programs (commercial product, research project, or otherwise) that you
  20.  * acknowledge this fact somewhere in the documentation, research report,
  21.  * etc...  If you like PCCTS and have developed a nice tool with the
  22.  * output, please mention that you developed it using PCCTS.  In
  23.  * addition, we ask that this header remain intact in our source code.
  24.  * As long as these guidelines are kept, we expect to continue enhancing
  25.  * this system and expect to make other tools available as they are
  26.  * completed.
  27.  *
  28.  * ANTLR 1.31
  29.  * Terence Parr
  30.  * Parr Research Corporation
  31.  * with Purdue University and AHPCRC, University of Minnesota
  32.  * 1989-1995
  33.  */
  34.  
  35. #ifndef APARSER_H_GATE
  36. #define APARSER_H_GATE
  37.  
  38. #include <stdio.h>
  39. #include <setjmp.h>
  40. #include "config.h"
  41. #include ATOKEN_H
  42. #include ATOKENBUFFER_H
  43.  
  44. #ifdef ZZCAN_GUESS
  45. #ifndef ZZINF_LOOK
  46. #define ZZINF_LOOK
  47. #endif
  48. #endif
  49.  
  50.  
  51. #define NLA            (token_type[lap&(LLk-1)])/* --> next LA */
  52.  
  53. typedef unsigned char SetWordType;
  54.  
  55. /* Define external bit set stuff (for SetWordType) */
  56. #define EXT_WORDSIZE    (sizeof(char)*8)
  57. #define EXT_LOGWORDSIZE    3
  58.  
  59.            /* s y n t a c t i c  p r e d i c a t e  s t u f f */
  60.  
  61. typedef struct _zzjmp_buf {
  62.             jmp_buf state;
  63.         } zzjmp_buf;
  64.  
  65. /* these need to be macros not member functions */
  66. #define zzGUESS_BLOCK        ANTLRParserState zzst; int zzrv; int _marker;
  67. #define zzNON_GUESS_MODE    if ( !guessing )
  68. #define zzGUESS_FAIL        guess_fail();
  69. #define zzGUESS_DONE        {inputTokens->rewind(_marker); guess_done(&zzst);}
  70. #define zzGUESS                saveState(&zzst); \
  71.                             guessing = 1; \
  72.                             _marker = inputTokens->mark(); \
  73.                             zzrv = setjmp(guess_start.state);
  74.  
  75.                   /* a n t l r  p a r s e r  d e f */
  76.  
  77. struct ANTLRParserState {
  78.     /* class variables */
  79.     zzjmp_buf guess_start;
  80.     int guessing;
  81.  
  82.     int inf_labase;
  83.     int inf_last;
  84.  
  85.     int dirty;
  86. };
  87.  
  88. /* notes:
  89.  *
  90.  * multiple inheritance is a cool way to include what stuff is needed
  91.  * in this structure (like guess stuff).  however, i'm not convinced that
  92.  * multiple inheritance works correctly on all platforms.  not that
  93.  * much space is used--just include all possibly useful members.
  94.  *
  95.  * the class should also be a template with arguments for the lookahead
  96.  * depth and so on.  that way, more than one parser can be defined (as
  97.  * each will probably have different lookahead requirements).  however,
  98.  * am i sure that templates work?  no, i'm not sure.
  99.  *
  100.  * no attributes are maintained and, hence, the 'asp' variable is not
  101.  * needed.  $i can still be referenced, but it refers to the token
  102.  * associated with that rule element.  question: where are the token's
  103.  * stored if not on the software stack?  in local variables created
  104.  * and assigned to by antlr.
  105.  */
  106. class ANTLRParser {
  107. protected:
  108.     /* class variables */
  109.     static SetWordType bitmask[sizeof(SetWordType)*8];
  110.     static char eMsgBuffer[500];
  111.  
  112. protected:
  113.     int LLk;                    // number of lookahead symbols (old LL_K)
  114.     int demand_look;
  115.     TokenType eofToken;            // when do I stop during resynch()s
  116.     int bsetsize;                // size of bitsets created by ANTLR in
  117.                                 // units of SetWordType
  118.  
  119.     ANTLRTokenBuffer *inputTokens;    //place to get input tokens
  120.  
  121.     zzjmp_buf guess_start;        // where to jump back to upon failure
  122.     int guessing;                // if guessing (using (...)? predicate)
  123.  
  124.     // infinite lookahead stuff
  125.     int can_use_inf_look;        // set by subclass (generated by ANTLR)
  126.     int inf_lap;
  127.     int inf_labase;
  128.     int inf_last;
  129.     ANTLRTokenBase **inf_token;
  130.     int *_inf_line;
  131.  
  132.     ANTLRChar **token_tbl;        // pointer to table of token type strings
  133.  
  134.     int dirty;                    // used during demand lookahead
  135.  
  136.     TokenType *token_type;        // fast reference cache of token.getType()
  137. //    ANTLRLightweightToken **token;    // the token with all its attributes
  138.     int lap;
  139.     int labase;
  140.  
  141. private:
  142.     void fill_inf_look();
  143.  
  144. protected:
  145.     void guess_fail()                { longjmp(guess_start.state, 1); }
  146.     void guess_done(ANTLRParserState *st){ restoreState(st); }
  147.     int guess(ANTLRParserState *);
  148.     void look(int);
  149.     int _match(TokenType, ANTLRChar **, TokenType *,
  150.                ANTLRLightweightToken **, SetWordType **);
  151.     int _setmatch(SetWordType *, ANTLRChar **, TokenType *,
  152.                ANTLRLightweightToken **, SetWordType **);
  153.     int _match_wsig(TokenType);
  154.     int _setmatch_wsig(SetWordType *);
  155.     virtual void consume();
  156.     void resynch(SetWordType *wd,SetWordType mask);
  157.     void prime_lookahead();
  158.     virtual void tracein(char *r)
  159.             {
  160.                 fprintf(stderr, "enter rule \"%s\"\n", r);
  161.             }
  162.     virtual void traceout(char *r)
  163.             {
  164.                 fprintf(stderr, "exit rule \"%s\"\n", r);
  165.             }
  166.     unsigned MODWORD(unsigned x) {return x & (EXT_WORDSIZE-1);}    // x % EXT_WORDSIZE
  167.     unsigned DIVWORD(unsigned x) {return x >> EXT_LOGWORDSIZE;}    // x / EXT_WORDSIZE
  168.     int set_deg(SetWordType *);
  169.     int set_el(TokenType, SetWordType *);
  170.     void edecode(SetWordType *);
  171.     void FAIL(int k, ...);
  172.  
  173. public:
  174.     ANTLRParser(ANTLRTokenBuffer *,
  175.                 int k=1,
  176.                 int use_inf_look=0,
  177.                 int demand_look=0,
  178.                 int bsetsize=1);
  179.     virtual ~ANTLRParser();
  180.  
  181.     virtual void init();
  182.     
  183.     TokenType LA(int i)
  184.     {
  185.         return demand_look ? token_type[(labase+(i)-1)&(LLk-1)] :
  186.                             token_type[(lap+(i)-1)&(LLk-1)];
  187.     }
  188.     ANTLRTokenBase *LT(int i);
  189.  
  190.     void setEofToken(TokenType t) { eofToken = t; }
  191.  
  192.     virtual void syn(ANTLRTokenBase *tok, ANTLRChar *egroup,
  193.                      SetWordType *eset, TokenType etok, int k);
  194.     void saveState(ANTLRParserState *);
  195.     void restoreState(ANTLRParserState *);
  196.  
  197.     void panic(char *msg);
  198.     static char *eMsgd(char *,int);
  199.     static char *eMsg(char *,char *);
  200.     static char *eMsg2(char *,char *,char *);
  201.  
  202.     void consumeUntil(SetWordType *st);
  203.     void consumeUntilToken(int t);
  204.  
  205.     virtual int _setmatch_wdfltsig(SetWordType *tokensWanted,
  206.                                      TokenType tokenTypeOfSet,
  207.                                      SetWordType *whatFollows);
  208.     virtual int _match_wdfltsig(TokenType tokenWanted,
  209.                                   SetWordType *whatFollows);
  210. };
  211.  
  212.  
  213. #define zzmatch(_t)                            \
  214.     if ( !_match((TokenType)_t, &zzMissText, &zzMissTok, \
  215.                  (ANTLRLightweightToken **) &zzBadTok, &zzMissSet) ) goto fail;
  216.  
  217. #define zzmatch_wsig(_t,handler)                        \
  218.     if ( !_match_wsig((TokenType)_t) ) {_signal=MismatchedToken; goto handler;}
  219.  
  220. #define zzsetmatch(_ts)                            \
  221.     if ( !_setmatch(_ts, &zzMissText, &zzMissTok, \
  222.                  (ANTLRLightweightToken **) &zzBadTok, &zzMissSet) ) goto fail;
  223.  
  224. #define zzsetmatch_wsig(_ts, handler)                \
  225.     if ( !_setmatch_wsig(_ts) ) {_signal=MismatchedToken; goto handler;}
  226.  
  227. /* For the dflt signal matchers, a FALSE indicates that an error occurred
  228.  * just like the other matchers, but in this case, the routine has already
  229.  * recovered--we do NOT want to consume another token.  However, when
  230.  * the match was successful, we do want to consume hence _signal=0 so that
  231.  * a token is consumed by the "if (!_signal) consume(); _signal=NoSignal;"
  232.  * preamble.
  233.  */
  234. #define zzsetmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) \
  235.     if ( !_setmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) ) \
  236.         _signal = MismatchedToken;
  237.  
  238. #define zzmatch_wdfltsig(tokenWanted, whatFollows) \
  239.     if ( !_match_wdfltsig(tokenWanted, whatFollows) ) _signal = MismatchedToken;
  240.  
  241.  
  242. #ifndef zzfailed_pred
  243. #define zzfailed_pred(_p)       \
  244.         zzNON_GUESS_MODE { fprintf(stderr, "semantic error; failed predicate: '%s'\n",_p); }
  245. #endif
  246.  
  247. #define zzRULE        SetWordType *zzMissSet=NULL; TokenType zzMissTok=(TokenType)0;    \
  248.                     ANTLRTokenBase *zzBadTok; ANTLRChar *zzBadText=(ANTLRChar *)"";    \
  249.                     int zzErrk=1;                                    \
  250.                     ANTLRChar *zzMissText=(ANTLRChar *)"";
  251.  
  252. #endif
  253.  
  254.         /* S t a n d a r d  E x c e p t i o n  S i g n a l s */
  255.  
  256. #define NoSignal            0
  257. #define MismatchedToken        1
  258. #define NoViableAlt            2
  259. #define NoSemViableAlt        3
  260.